import {useAuthStore} from '@/store/modules/auth'
import {ApiRequestConfig, ApiRequestInterceptors, ApiResponse} from '@/typings/axios'
import {AxiosInstance, AxiosResponse, InternalAxiosRequestConfig,} from 'axios'
import camelcaseKeys from "camelcase-keys";

// 将axios封装到类中
class Axios {
	instance: AxiosInstance //axios的实例将被保存到这里
	interceptors?: ApiRequestInterceptors //获取到的interceptors将被保存到这里
	constructor(config: ApiRequestConfig) {
		// 构造器里的config包括baseURL，timeout等
		this.instance = axios.create(config) // 创建axios实例，并保存
		this.interceptors = config.interceptors // 从传进来的config对象中取出key为interceptors的value并保存
		// 全局请求拦截器
		this.instance.interceptors.request.use((request: InternalAxiosRequestConfig) => request, (err: any) => err)
		// 使用实例拦截器
		this.instance.interceptors.request.use(
			// @ts-ignore
			this.interceptors?.requestInterceptor,
			this.interceptors?.requestInterceptorCatch
		)
		this.instance.interceptors.response.use(
			this.interceptors?.responseInterceptor,
			this.interceptors?.responseInterceptorCatch
		)
		// 全局响应拦截器
		this.instance.interceptors.response.use((response: AxiosResponse) => {
			let pattern = new RegExp('.+/api/chat_message/send')
			if (!pattern.test(response.request.responseURL)) {
				const data = camelcaseKeys(response.data, {deep: true});
				if (data.code === 200 || typeof data === 'string') {
					return data.data
				}
				throw new Error(data.message || response.status.toString())
			} else {
				if (response.status == 200) return response.data
				throw new Error(response.status.toString())
			}

		}, error => {
			if (!error.response) {
				throw new Error('ok，执行取消啦')
			}
			const data: ApiResponse = error.response.data
			const authStore = useAuthStore()
			switch (data.code) {
				case 400:
					throw new Error(data.message || 'Error')
				case 401:
					authStore.removeToken()
					throw new Error(data.message || 'Error')
				default:
					let msg
					if (error.message === 'Network Error') {
						msg = '服务连接异常，请联系管理员'
					} else if (error.message.includes('timeout')) {
						msg = '请求超时，请联系管理员'
					} else if (error.message.includes('Request failed with status code')) {
						msg = '系统接口' + error.message.substring(error.message.length - 3) + '异常，请联系管理员'
					}
					throw new Error(msg || error.message)
			}
		})

	}

	request<T>(config: ApiRequestConfig<T>): Promise<T> {
		// 再次封装request方法
		return new Promise((resolve, reject) => {
			if (config.interceptors?.requestInterceptor) {
				config = config.interceptors.requestInterceptor(config)
			}
			this.instance.request<any, T>(config).then((response: any) => {
				if (config.interceptors?.responseInterceptor) {
					response = config.interceptors.responseInterceptor(response)
				}
				resolve(response)
			}).catch((err) => {
				console.log(err)
				reject(err)
				return err
			})
		})
	}

	get<T = any>(config: ApiRequestConfig<T>): Promise<T> {
		return this.request<T>({
			...config,
			method: 'GET'
		})
	}

	post<T = any>(config: ApiRequestConfig<T>): Promise<T> {
		return this.request<T>({
			...config,
			method: 'POST'
		})
	}

	put<T = any>(config: ApiRequestConfig<T>): Promise<T> {
		return this.request<T>({
			...config,
			method: 'PUT'
		})
	}

	delete<T = any>(config: ApiRequestConfig<T>): Promise<T> {
		return this.request<T>({
			...config,
			method: 'DELETE'
		})
	}

	patch<T = any>(config: ApiRequestConfig<T>): Promise<T> {
		return this.request<T>({
			...config,
			method: 'PATCH'
		})
	}
}

export default Axios
